home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#18 (Mar 87)
/
Printer LSP sources
/
PrintingStuff
< prev
next >
Wrap
Text File
|
1987-02-13
|
9KB
|
223 lines
UNIT Printing;
INTERFACE
USES
MacPrint, MyGlobals, Windows;
PROCEDURE DoPrinting;
IMPLEMENTATION
{---------Print out a document window-----------}
PROCEDURE DoPrinting;
CONST
bottommargin = 20;{ margins (in pixels) for document, inset from rPage }
leftmargin = 30;
rightmargin = 10;
topmargin = 36;
VAR
txth : Handle;
printTE : TEHandle;
MyPPort : TPPrPort;
dlogptr : DialogPtr;
txtptr : Ptr;
linesperpage, height, firstoffset, lastoffset, leftpos, toppos, fstpos, lineno, lastline, linecount, pageno, firstpage, lastpage, numpages, copyno, numpasses, dummyitem, errno : INTEGER;
pagerect : Rect;
currstr, laststr, heading : Str255;
strh0, strh1, hdgstrh : StringHandle;
status : TPrStatus;
info : FontInfo;
lastonpage : ARRAY[0..99] OF INTEGER; { last line # on each page }
BEGIN
{ This section images each page, using QuickDraw via TextEdit}
{ A few special cases:}
{ 1. For spooled output (IW only), must image and then print}
{ 2. For IW draft mode, must send multiple copies ourself}
{ This has been completely rewritten from skeleton code, for a number}
{ of key reasons:}
{ 1. A location is calculated for each line and then DrawText is}
{ used to draw the line. This also requires setting the font}
{ directly in the printing GrafPort. The skeleton used TextBox}
{ for each page; TextBox uses an EraseRect which, according to}
{ Technical Note #72, is very slow on the LaserWriter.}
{ 2. We use crOnly, so only actual returns are used for line}
{ breaks. Thus, we don't need a new TECalText for the}
{ printing destRect, but instead use the TextEdit lineStarts}
{ established for display purposes.}
{ 3. This routine figures out what the actual pages selected are,}
{ and then prints only those pages. (The values of prJob.iFstPage}
{ and iLstPage need to be fudged to do this.)}
{ 4. Put a heading on each page, showing page number.}
{ 5. Put up an Alert if a printing error is encountered. Not strictly}
{ necessary, since the most commonly found "errors" are user-}
{ specified aborts that should be ignored.}
{}
printFlag := FALSE; { so we don't print again }
DialogueDeactivate;
IF PrJobDialog(printHdl) THEN
BEGIN
SetCursor(watchHdl^^);
{ Put up progress dialog }
strh0 := GetString(STR_prepare);
ParamText(strh0^^, '', '', '');
dlogptr := GetNewDialog(DLOG_printing, NIL, Pointer(-1));
DrawDialog(dlogptr);
printTE := hTE;
{ Calculate number of pages, and line numbers for each page }
WITH printTE^^, printHdl^^.PrInfo DO
BEGIN
txth := hText;
height := lineHeight;
linecount := nLines;
linesperpage := (rPage.bottom - rPage.top - bottommargin - topmargin) DIV height;
pagerect := rPage; { top margin allows for heading }
pagerect.left := pagerect.left + leftmargin;
pagerect.right := pagerect.right - rightmargin;
pagerect.bottom := pagerect.top + topmargin + (linesperpage * height);
fstpos := pagerect.top + topmargin + fontAscent;
{ base line of first line of text in document }
END; {WITH}
lastonpage[0] := 0;
pageno := 1;
lineno := 0;
WHILE lineno < linecount DO { until we run out of pages }
BEGIN
lineno := lineno + linesperpage;
IF lineno < linecount THEN { all but last page }
lastonpage[pageno] := lineno - 1 { last line on this page }
ELSE { last page }
lastonpage[pageno] := linecount - 1;{ lines numbered 0..n }
pageno := pageno + 1;
END; {WHILE}
numpages := pageno - 1;
{ We could skip page calculations, but then we would image all pages and}
{ Print Manager would print only those selected. Obviously this is}
{ inefficient for large documents. Instead, fool Print Manager into}
{ thinking enough pages are selected and then do actual printing starting}
{ at the selected page. This MUST be done before PrOpenDoc. }
WITH printHdl^^.PrJob DO
BEGIN
firstpage := iFstPage; { page numbers requested }
IF firstpage < 1 THEN
firstpage := 1;
lastpage := iLstPage;
IF lastpage > numpages THEN
lastpage := numpages; { limit to available pages }
numpages := lastpage - firstpage + 1; { actual length }
iFstPage := 1; { fool print manager }
iLstPage := numpages; { reset by next PrJobDialog }
{ Manual handling of multiple copies for draft mode only}
{ ImageWriter spooling handles this directly; the LaserWriter PrJobDialog}
{ always sets iCopies := 1 and hides the actual number of copies from us}
{ Also set up appropriate progress message }
IF bJDocLoop = bSpoolLoop THEN
BEGIN
numpasses := 1; { only one pass through }
strh0 := GetString(STR_spooling);{ "Now spooling " }
END
ELSE
BEGIN
numpasses := iCopies; { draft mode, multiple passes }
strh0 := GetString(STR_printing);{ "Now printing " }
END;
END; {WITH}
strh1 := GetString(STR_of); { " of " }
hdgstrh := GetString(STR_pagehead); { "Page " }
{ Now do actual printing (or imaging, for spool mode}
{ Get a drawing port: TPrint should be frozen by now}
{ Go through it once for every copy (if necessary) and once per page }
{ Show dialog progress in terms of pages to be printed }
MyPPort := PrOpenDoc(printHdl, NIL, NIL);
NumToString(numpages, laststr); { actual # of pages to print }
FOR copyno := 1 TO numpasses DO
BEGIN
MoveHHi(txth);
HLock(txth);
txtptr := txth^;
FOR pageno := firstpage TO lastpage DO
BEGIN { Image each page; this does printing for draft mode }
IF PrError = noErr THEN
BEGIN
NumToString(pageno - firstpage + 1, currstr); {relative page #}
ParamText(strh0^^, currstr, strh1^^, laststr);
DrawDialog(dlogptr); { update the status }
PrOpenPage(MyPPort, NIL); { changes GrafPort for us }
{ First put a heading on the page. Since MoveTo location for drawing text}
{ is the base line, need ascent to position heading within pagerect }
TextFont(myHdgFont);
TextSize(myHdgSize);
GetFontInfo(info); { need ascent height }
NumToString(pageno, heading); { absolute page number }
heading := Concat(hdgstrh^^, heading); { "Page 1" }
WITH pagerect DO
BEGIN
leftpos := left + ((right - left - StringWidth(heading)) DIV 2); { center }
MoveTo(leftpos, top + info.ascent); { base line }
DrawString(heading); { print page heading }
{ Now print actual document for this page }
leftpos := left; { left margin for text }
toppos := fstpos; { base line for 1st line }
END;
TextFont(printTE^^.txFont); { set for display }
TextSize(printTE^^.txSize);
lineno := lastonpage[pageno - 1];{ line of TERec }
firstoffset := printTE^^.lineStarts[lineno];
lastline := lastonpage[pageno];
{ Draw each line in TERec, excluding CR at end of line }
WHILE lineno <= lastline DO
BEGIN
MoveTo(leftpos, toppos);
lineno := lineno + 1;
IF lineno >= linecount THEN
lastoffset := printTE^^.teLength { very last line }
ELSE
lastoffset := printTE^^.lineStarts[lineno] - 1;
DrawText(txtptr, firstoffset, lastoffset - firstoffset);
toppos := toppos + height;
firstoffset := lastoffset + 1;
END; {each line}
PrClosePage(MyPPort); { done with this page }
END; {If no Prerror}
END; {for each page}
HUnLock(txth);
END; {each copy}
PrCloseDoc(MyPPort);
{ If spooled, the file is now imaged and now need to print it }
IF (printHdl^^.prJob.BJDocLoop = BSpoolLoop) AND (PrError = noErr) THEN
BEGIN
strh0 := GetString(STR_prspool); { "Now printing spool file" }
ParamText(strh0^^, '', '', '');
DrawDialog(dlogptr);
PrPicFile(printHdl, NIL, NIL, NIL, status);
END;
{ Drop the advice dialog }
DisposDialog(dlogptr);
SetCursor(arrow);
errno := PrError;
IF (errno <> noErr) AND (errno <> iPrAbort) AND (errno <> iIOAbort) THEN { indicate a printing error, unless… }
{ user hit command-period }
{ user cancel on "not responding" alert }
BEGIN
NumToString(errno, currstr); { error number }
ParamText(currstr, '', '', ''); { should be more user-friendly }
dummyitem := StopAlert(ALRT_printerr, NIL);
END;
END {IF PrJobDialog}
ELSE { Cancel in PrJobDlog }
PrSetError(iPrAbort);
END; {DoPrinting}
END.